"""
B站弹幕监听服务
负责连接B站直播间并实时接收弹幕消息
"""

import asyncio
import time
from typing import Callable, Optional
from datetime import datetime
import hashlib

from bilibili_api import live, sync, Credential

from ..core.models import DanmakuMessage, MessageType
from ..utils.logger import get_logger


class BilibiliDanmakuListener:
    """B站弹幕监听器"""

    def __init__(
        self,
        room_id: int,
        on_message_callback: Callable[[DanmakuMessage], None],
        max_reconnect: int = 5,
        reconnect_delay: int = 5
    ):
        """
        初始化弹幕监听器
        
        Args:
            room_id: B站直播间ID
            on_message_callback: 接收到消息时的回调函数
            max_reconnect: 最大重连次数
            reconnect_delay: 重连延迟(秒)
        """
        self.room_id = room_id
        self.on_message_callback = on_message_callback
        self.max_reconnect = max_reconnect
        self.reconnect_delay = reconnect_delay

        self.room: Optional[live.LiveDanmaku] = None
        self.is_running = False
        self.reconnect_count = 0
        self.logger = get_logger()

    async def start(self):
        """启动弹幕监听"""
        self.logger.info(f"正在连接B站直播间: {self.room_id}")
        self.is_running = True

        while self.is_running and self.reconnect_count < self.max_reconnect:
            try:
                # 创建直播间对象
                self.room = live.LiveDanmaku(self.room_id)

                # 注册事件处理器
                @self.room.on('DANMU_MSG')
                async def on_danmaku(event):
                    """处理弹幕消息"""
                    await self._handle_danmaku(event)

                @self.room.on('SEND_GIFT')
                async def on_gift(event):
                    """处理礼物消息"""
                    await self._handle_gift(event)

                @self.room.on('WELCOME')
                async def on_welcome(event):
                    """处理用户进入直播间"""
                    await self._handle_welcome(event)

                @self.room.on('SUPER_CHAT_MESSAGE')
                async def on_super_chat(event):
                    """处理醒目留言"""
                    await self._handle_super_chat(event)

                @self.room.on('GUARD_BUY')
                async def on_guard_buy(event):
                    """处理上舰消息"""
                    await self._handle_guard_buy(event)

                # 连接并监听
                self.logger.info("✓ 成功连接到B站直播间")
                self.reconnect_count = 0  # 重置重连计数
                await self.room.connect()

            except Exception as e:
                self.logger.error(f"弹幕监听异常: {e}")
                self.reconnect_count += 1

                if self.reconnect_count < self.max_reconnect:
                    self.logger.warning(
                        f"将在 {self.reconnect_delay} 秒后重连 "
                        f"({self.reconnect_count}/{self.max_reconnect})"
                    )
                    await asyncio.sleep(self.reconnect_delay)
                else:
                    self.logger.critical("已达到最大重连次数,停止监听")
                    self.is_running = False

    async def stop(self):
        """停止弹幕监听"""
        self.logger.info("正在停止弹幕监听...")
        self.is_running = False
        if self.room:
            await self.room.disconnect()
        self.logger.info("✓ 弹幕监听已停止")

    async def _handle_danmaku(self, event: dict):
        """
        处理弹幕消息
        
        Args:
            event: 弹幕事件数据
        """
        try:
            data = event.get('data', {})
            info = data.get('info', [])

            if len(info) < 3:
                return

            # 提取弹幕信息
            content = info[1]  # 弹幕内容
            user_info = info[2]  # 用户信息
            user_id = str(user_info[0]) if len(user_info) > 0 else "unknown"
            username = user_info[1] if len(user_info) > 1 else "匿名用户"

            # 提取用户等级信息
            medal_info = info[3] if len(info) > 3 else []
            is_vip = len(info) > 7 and info[7] > 0
            is_guard = len(medal_info) > 10 and medal_info[10] > 0

            # 创建消息对象
            message = DanmakuMessage(
                message_id=self._generate_message_id(user_id, content),
                user_id=user_id,
                username=username,
                content=content,
                message_type=MessageType.DANMAKU,
                is_vip=is_vip,
                is_guard=is_guard
            )

            # 输出详细的弹幕日志
            self.logger.info(f"📨 弹幕 [{username}]: {content}")
            self.logger.debug(f"   用户ID: {user_id} | VIP: {is_vip} | 舰长: {is_guard}")

            # 调用回调函数
            if self.on_message_callback:
                self.on_message_callback(message)
                self.logger.debug(f"   已加入消息队列")

        except Exception as e:
            self.logger.error(f"处理弹幕消息失败: {e}")

    async def _handle_gift(self, event: dict):
        """处理礼物消息"""
        try:
            data = event.get('data', {})
            username = data.get('uname', '匿名用户')
            gift_name = data.get('giftName', '礼物')
            num = data.get('num', 1)

            content = f"赠送了 {num} 个{gift_name}"

            message = DanmakuMessage(
                message_id=self._generate_message_id(username, content),
                user_id=str(data.get('uid', 'unknown')),
                username=username,
                content=content,
                message_type=MessageType.GIFT,
                is_vip=True,
                priority=5
            )

            self.logger.info(f"🎁 礼物 [{username}]: {content}")

            if self.on_message_callback:
                self.on_message_callback(message)

        except Exception as e:
            self.logger.error(f"处理礼物消息失败: {e}")

    async def _handle_welcome(self, event: dict):
        """处理用户进入直播间"""
        # 默认不处理进入消息,避免刷屏
        pass

    async def _handle_super_chat(self, event: dict):
        """处理醒目留言(SC)"""
        try:
            data = event.get('data', {})
            username = data.get('user_info', {}).get('uname', '匿名用户')
            content = data.get('message', '')
            price = data.get('price', 0)

            message = DanmakuMessage(
                message_id=self._generate_message_id(username, content),
                user_id=str(data.get('uid', 'unknown')),
                username=username,
                content=content,
                message_type=MessageType.SUPER_CHAT,
                is_vip=True,
                priority=15  # SC优先级最高
            )

            self.logger.info(f"收到醒目留言 [{username}] ¥{price}: {content}")

            if self.on_message_callback:
                self.on_message_callback(message)

        except Exception as e:
            self.logger.error(f"处理醒目留言失败: {e}")

    async def _handle_guard_buy(self, event: dict):
        """处理上舰消息"""
        try:
            data = event.get('data', {})
            username = data.get('username', '匿名用户')
            guard_level = data.get('guard_level', 3)
            guard_names = {1: '总督', 2: '提督', 3: '舰长'}
            guard_name = guard_names.get(guard_level, '舰长')

            content = f"购买了{guard_name}"

            message = DanmakuMessage(
                message_id=self._generate_message_id(username, content),
                user_id=str(data.get('uid', 'unknown')),
                username=username,
                content=content,
                message_type=MessageType.GUARD_BUY,
                is_guard=True,
                priority=10
            )

            self.logger.info(f"收到上舰 [{username}]: {content}")

            if self.on_message_callback:
                self.on_message_callback(message)

        except Exception as e:
            self.logger.error(f"处理上舰消息失败: {e}")

    def _generate_message_id(self, user_id: str, content: str) -> str:
        """
        生成消息唯一ID
        
        Args:
            user_id: 用户ID
            content: 消息内容
            
        Returns:
            消息ID
        """
        timestamp = str(time.time())
        raw = f"{user_id}_{content}_{timestamp}"
        return hashlib.md5(raw.encode()).hexdigest()[:16]
